`include "define.sv"
module C_fifo_to_array (
    input clk,
    input reset,
    input [1:0]matrix_type,
    input [31:0] data_in_c,
    input data_valid_in_c,
    // 下游信号
    output reg [31:0] data_out_c [0:15][0:15],
    output reg wr_en_c [0:15][0:15],
    input array_ready,
    output reg done
);

    reg [7:0] counter;

always @(posedge clk or posedge reset) begin
    if (reset) begin
        counter <= 8'd0;
    end
    else if(array_ready && data_valid_in_c) begin
        counter <= counter + 1;
    end
end

always @(posedge clk or posedge reset) begin
    if (reset) begin
        for (int i = 0; i < 16; i++) begin
            for (int j = 0; j < 16; j++) begin
                data_out_c[i][j] <= 32'd0;
                wr_en_c[i][j] <= 1'b0;
            end
        end
    end 
    else if(array_ready && data_valid_in_c) begin
        case (matrix_type)
            `m16n16k16: begin
                // 16x16矩阵：直接使用counter作为索引
                data_out_c[counter[7:4]][counter[3:0]] = data_in_c;
                wr_en_c[counter[7:4]][counter[3:0]] = 1'b1;
            end
            `m8n32k16: begin
                // 8x32矩阵：需要重新映射索引
                // 对于8x32矩阵，PE阵列的映射关系：
                // pe[0][0]->pe[7][7] 构成左半边（第1-16列）
                // pe[8][0]->pe[15][15] 构成右半边（第17-32列）
                // counter[7:4]作为行索引，counter[3:0]作为列索引
                if (counter[4:0] < 5'd16) begin
                    // 左半边：pe[0][0]->pe[7][15] -> 输出矩阵的[0:7][0:15]
                data_out_c[counter[7:5]][counter[4:0]] <= data_in_c;
                end 
                else if(counter[4:0] >= 5'd16)begin
                    // 右半边：pe[8][0]->pe[15][15] -> 输出矩阵的[0:7][16:31]
                    data_out_c[counter[7:5] + 5'd8][counter[4:0] - 5'd16] <= data_in_c;
                end
            end
            `m32n8k16: begin
                // 32x8矩阵：需要重新映射索引
                // 对于32x8矩阵，PE阵列的映射关系：
                // pe[0][0]->pe[15][7] 构成上半边（第1-16行）
                // pe[16][0]->pe[31][7] 构成下半边（第17-32行）
                // counter[7:4]作为行索引，counter[3:0]作为列索引
                if (counter[7:3] < 5'd16) begin
                    // 上半边：pe[0][0]->pe[15][7] -> 输出矩阵的[0:15][0:7]
                    data_out_c[counter[7:3]][counter[2:0]] <= data_in_c;
                end 
                else if(counter[7:3] >= 5'd16) begin
                    // 下半边：pe[16][0]->pe[31][7] -> 输出矩阵的[16:31][0:7]
                    data_out_c[counter[7:3] - 5'd16][counter[2:0] + 4'd8] <= data_in_c;
                end
            end
            default: begin
                data_out_c[counter[7:4]][counter[3:0]] = data_out_c[counter[7:4]][counter[3:0]];
                wr_en_c[counter[7:4]][counter[3:0]] = 1'b0;
            end
        endcase
    end
end

always @(posedge clk or posedge reset) begin
    if (reset) begin
        done <= 1'b0;
    end
    else if(counter == 8'd255) begin
        done <= 1'b1;
    end
end


endmodule